/**
 * Reflect
 * Object 语言内部方法放到 Reflect
 * 修改Object 方法返回结果
 * Object 操作变为函数行为
 * Reflect 与Proxy 方法一一对应
 */
let obj = {}
let newName = ''
Reflect.defineProperty(obj, 'name', {
  get(){
    return newName
  },
  set(val){
    console.log('set')
    newName = val
  }
})
console.log(obj.name)
obj.name = '啊切'
console.log(obj.name)

Reflect.defineProperty(obj,'age',{}) // 2.能定义属性返回true

// 判断当前对象存在方法
console.log('assign' in Object)             // 命令式
console.log(Reflect.has(Object, 'assign'))  // 函数式



let userInfo = {
  username:'aqie',
  age:18,
  _password: '888'
}
userInfo = new Proxy(userInfo, {
  get(target, prop){
    if(prop.startsWith('_')) {
      throw new Error('不可访问')
    } else {
      return Reflect.get(target, prop)
    }
  },
  set(target, prop, val){
    if(prop.startsWith('_')){
      throw new Error('不可修改')
    }else{
      Reflect.set(target, prop, val)
      return true
    }
  },
  deleteProperty(target, prop){ // 删除拦截
    if(prop.startsWith('_')){
      throw new Error('不可删除')
    }else{
      Reflect.deleteProperty(target, prop)
      return true
    }
  },
  ownKeys(target) {
    // return Object.keys(target).filter(key => !key.startsWith('_'))
    return Reflect.ownKeys(target).filter(key => !key.startsWith('_'))
  }
})

try {
  console.log(userInfo._password)
} catch (error) {
  console.log(error)
}

userInfo.age = 24
console.log(userInfo.age)

for(let key in userInfo){
  console.log(key)
}



// apply 拦截函数调用 call  apply
let sum= (...arg) => {
  let num = 0
  arg.forEach(item => {
    num += item
  })
  return num
}

sum = new Proxy(sum, {
  // 目标 上下文 参数
  apply(target,ctx, args) {
    // return target(...args) * 2
    return Reflect.apply(target, target, [...args]) * 2
  }
})

console.log(sum(1,2))
console.log(sum.call(null, 1,2,3)) // call 改变this 指向
console.log(sum.apply(null, [1,2,3])) 
